import jsapi from '../jsapi';
import { layerCreator } from '@/utils/arcgis';
import geometryUtils from '../geometry';

let viewCache = {};
/**
 * 判断当前view是否准备好
 * @author  lwei
 * @param
 * @returns {object}  promise
 */
export function isViewReady(getViewFn = () => window.agsGlobal.view) {
  let timer;
  let _fnStr = '' + getViewFn; // 用于对比函数内容
  // 读取缓存
  if (viewCache[_fnStr]) {
    return viewCache[_fnStr];
  }

  // 包裹错误
  let _getViewFn = () => {
    try {
      return getViewFn();
    } catch (error) {
      console.error(error, '获取view失败，请检查获取函数');
      return null;
    }
  };

  // view已经加载可以直接获取
  if (_getViewFn()) {
    return new Promise(resolve => resolve(_getViewFn()));
  }

  //  view还在加载时
  viewCache[_fnStr] = new Promise(reslove => {
    timer = setInterval(() => {
      if (_getViewFn()) {
        clearInterval(timer);
        reslove(_getViewFn());
      }
    }, 300);
  });

  return viewCache[_fnStr];
}

/**
 * 关掉目标图层外的剩余图层
 * @param {string | string[]} targetLayersTitle 不被关掉的图层title,可传单个title
 * @param {undefined |  object} config 被关掉图层的配置，默认不传
 * 可设置setVisiable：true只隐藏其他图层（不删除）
 * 可设置beforeTurnOff 回调 （lyr，index）
 * @param {undefined | object} view 可选默认使用isViewReady中返回的view
 */
export async function turnOffRestLayers(targetLayersTitle, config, _view) {
  let view = _view || (await isViewReady());
  let restTitles = [];
  if (!Array.isArray(targetLayersTitle)) {
    targetLayersTitle = [targetLayersTitle];
  }
  const restLayers = view.map.layers.filter(lyr => {
    let isNeedTurnOff = targetLayersTitle.indexOf(lyr.title) === -1;
    if (isNeedTurnOff) {
      restTitles.push(lyr.title);
    }
    return isNeedTurnOff;
  });
  process.env.NODE_ENV === 'development' && console.log('---以下图层将被关闭---', restTitles);
  if (!config) {
    view.map.removeMany(restLayers);
    return;
  }

  restLayers.forEach((item, i) => {
    // 执行回调关闭前的回调用于处理弹框之类的
    config.beforeTurnOff(item, i);
    // 配置了setVisiable，只隐藏
    if (config.setVisiable) {
      item.item = false;
    }
  });
  // 没有配置setVisiable，删除图层
  !config.setVisiable && view.map.removeMany(restLayers);
}

/**
 * 初始化底图
 * @author  lee
 * @param {object} opt  设置底图的参数
 * @returns {object}  basemap 底图
 */
async function createBasemap(opt) {
  const [Basemap] = await jsapi.load(['esri/Basemap']);

  const baseLayers = [];
  for (let i = 0; i < opt.baseLayers.length; i++) {
    const lyr = await layerCreator.create(opt.baseLayers[i]);
    baseLayers.push(lyr);
  }

  var basemap = new Basemap({
    baseLayers: baseLayers,
    title: opt.title,
    id: opt.id,
  });
  return basemap;
}
/**
 * 初始化二维场景
 * @author  lee
 * @param {object} opt  portal container extent
 * @returns {object}  view 场景
 */
async function initMapView(opt) {
  const [Map, MapView] = await jsapi.load(['esri/Map', 'esri/views/MapView']);

  const map = new Map({
    basemap: opt.basemap || 'dark-gray-vector',
  });

  const view = new MapView({
    container: opt.container,
    map: map,
    ui: {
      components: [],
    },
    zoom: 8,
    popup: {
      defaultPopupTemplateEnabled: true, // 自动创建要素图层的popuptemplate
    },
  });
  if (opt.extent) {
    const extent = await geometryUtils.jsonToExtent(opt.extent);
    view.extent = extent;
  }

  return view;
}

/**
 * 初始化二维场景
 * @author  lee
 * @param {object} portal  portal地址
 * @param {string} itemid  webmapId
 * @param {string} container  地图的div
 * @returns {object}  view 场景
 */
async function initMapViewByPortal(portal, itemid, container) {
  const [WebMap, MapView] = await jsapi.load(['esri/WebMap', 'esri/views/MapView']);
  const webmap = new WebMap({
    portalItem: {
      id: itemid,
      portal: portal,
    },
  });
  const view = new MapView({
    container: container,
    map: webmap,
    ui: {
      components: [],
    },
  });
  return view;
}

/**
 * 初始化二维场景
 * @author  lee  mapviewer-01
 * @param {object} opt  portal container extent
 * @returns {object}  view 场景
 */
async function initSceneView(opt, store) {
  const [Map, ScenesView, WebScene] = await jsapi.load([
    'esri/Map',
    'esri/views/SceneView',
    'esri/WebScene',
  ]);
  console.log('optopt-------------------------', opt);
  let map = null;
  const state = opt.basemap.title === '矢量切片底图';
  if (state) {
    map = new Map({
      basemap: opt.basemap || 'satellite',
    });
  } else {
    map = new WebScene({
      portalItem: {
        id: 'c56dab9e4d1a4b0c9d1ee7f589343516',
      },
    });
  }

  if (opt.layers) {
    map.layers = opt.layers;
  }

  const view = new ScenesView({
    container: opt.container,
    map: map,
    environment: {
      weather: {
        type: 'sunny',
        cloudCover: 0.8,
      },
    },
    ui: {
      components: [],
    },
    popup: {
      defaultPopupTemplateEnabled: true,
      collapseEnabled: false,
      actions: [],
      featureNavigationEnabled: false,
      dockOptions: {
        buttonEnabled: false,
      },
    },
    qualitySettings: {
      memoryLimit: 8192,
    },
  });

  view.when(() => {
    // Find the layer for the
    let floodLevel = map.allLayers.find(function(layer) {
      return layer.title === 'Flood Level';
    });
    // view.environment.weather = {
    //   type: 'rainy', // autocasts as new RainyWeather({ cloudCover: 0.7, precipitation: 0.3 })
    //   cloudCover: 0.7,
    //   precipitation: 0.3,
    // floodLevel.visible = true;
  });
  if (opt.camera) {
    view.camera = opt.camera;
  }

  return view;
}
/**
 * 初始化三维场景
 * @author  lee
 * @param {object} portal  portal地址
 * @param {string} itemid  webscenenId
 * @param {string} container  地图的div
 */
async function initSceneViewByPortal(portal, itemid, container) {
  const [WebScene, Sceneview] = await jsapi.load(['esri/WebScene', 'esri/views/SceneView']);
  const scene = new WebScene({
    portalItem: {
      id: itemid,
      portal: portal,
    },
  });

  const view = new Sceneview({
    container: container,
    map: scene,
    environment: {
      atmosphere: {
        // creates a realistic view of the atmosphere
        quality: 'high',
      },
    },
    ui: {
      components: [], // 'zoom', 'navigation-toggle', 'compass'
    },
    popup: {
      autoOpenEnabled: false,
      collapsed: false,
      dockEnabled: true,
      dockOptions: {
        breakpoint: false,
        position: 'bottom-center',
      },
    },
  });
  return view;
}

/**
 * 通过webmapid 切换地图的webmap
 * @author  lee
 * @param {object} portal  portal
 * @param {object} view 场景
 * @param {string} webmapId webmap的itmid
 */
async function swapWebmap(portal, view, webmapId) {
  const [WebMap] = await jsapi.load(['esri/WebMap']);
  const webmap = new WebMap({
    portalItem: {
      id: webmapId,
      portal: portal,
    },
  });
  view.map = webmap;
}

/**
 * 通过webmapid 切换底图  适用于二三维场景
 * @author  lee
 * @param {object} view 场景
 * @param {string} webmapId webmap的itmid
 */
async function switchBaseMapByWebmapId(view, webmapId) {
  const [WebMap] = await jsapi.load(['esri/WebMap']);
  const map = new WebMap({
    portalItem: {
      id: webmapId,
    },
  });
  map.load().then(function() {
    map.basemap.load().then(function() {
      view.map.basemap = map.basemap;
    });
  });
}

/**
 * 环绕漫游（heading）比如：沿着建筑漫游
 * @author  lee  sceneviewer-02
 * @param {object} view  三维场景
 */
let roamHandle;
function roamByHeading(view) {
  if (roamHandle) {
    clearInterval(roamHandle);
    roamHandle = null;
  } else {
    roamHandle = setInterval(() => {
      view.goTo({ heading: view.camera.heading + 0.5 });
    }, 100);
  }
}
/**
 * 环绕漫游 环绕漫游（longitude）比如：整个地图旋转
 * @author  lee  sceneviewer-03
 * @param {object} view  三维场景
 */
let roamByLongtitudeInterval;
function roamByLongtitude(view) {
  if (roamByLongtitudeInterval) {
    clearInterval(roamByLongtitudeInterval);
    roamByLongtitudeInterval = null;
  } else {
    roamByLongtitudeInterval = setInterval(() => {
      const camera = view.camera.clone();
      camera.position.longitude += 5;
      view.goTo(camera);
    }, 100);
  }
}

const viewUtil = {
  isViewReady,
  createBasemap,
  initMapView,
  initMapViewByPortal,
  initSceneView,
  initSceneViewByPortal,
  swapWebmap,
  switchBaseMapByWebmapId,
  roamByHeading,
  roamByLongtitude,
};

export default viewUtil;
